package com.devenv.controller;

import com.devenv.dto.*;
import com.devenv.entity.User;
import com.devenv.service.UserService;
import com.devenv.common.Result;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.Max;

/**
 * 用户控制器
 * <p>
 * 提供用户相关的REST API接口，包括注册、登录、个人信息管理等功能
 * </p>
 * 
 * @author DevEnv OpenSource Team
 * @version 1.0.0
 * @since 1.0.0
 */
@Slf4j
@RestController
@RequestMapping("/api/users")
@RequiredArgsConstructor
@Validated
public class UserController {

    private final UserService userService;

    /**
     * 用户注册
     */
    @PostMapping("/register")
    public ResponseEntity<Result<UserDTO>> register(@Valid @RequestBody RegisterRequest request) {
        log.info("用户注册请求，用户名: {}", request.getUsername());
        try {
            UserDTO userDTO = userService.register(request);
            return ResponseEntity.ok(Result.success(userDTO, "注册成功"));
        } catch (Exception e) {
            log.error("用户注册失败", e);
            return ResponseEntity.badRequest().body(Result.error(e.getMessage()));
        }
    }

    /**
     * 用户登录
     */
    @PostMapping("/login")
    public ResponseEntity<Result<LoginResponse>> login(@Valid @RequestBody LoginRequest request, HttpServletRequest httpRequest) {
        log.info("用户登录请求，用户名: {}", request.getUsername());
        try {
            String clientIp = getClientIp(httpRequest);
            LoginResponse response = userService.login(request, clientIp);
            return ResponseEntity.ok(Result.success(response, "登录成功"));
        } catch (Exception e) {
            log.error("用户登录失败", e);
            return ResponseEntity.badRequest().body(Result.error(e.getMessage()));
        }
    }

    /**
     * 用户登出
     */
    @PostMapping("/logout")
    public ResponseEntity<Result<String>> logout(@RequestHeader("Authorization") String token) {
        log.info("用户登出请求");
        try {
            userService.logout(token);
            return ResponseEntity.ok(Result.success(null, "登出成功"));
        } catch (Exception e) {
            log.error("用户登出失败", e);
            return ResponseEntity.badRequest().body(Result.error(e.getMessage()));
        }
    }

    /**
     * 获取当前用户信息
     */
    @GetMapping("/profile")
    public ResponseEntity<Result<UserDTO>> getCurrentUserProfile(@RequestHeader("Authorization") String token) {
        log.debug("获取当前用户信息请求");
        try {
            User user = userService.getCurrentUser(token);
            UserDTO userDTO = convertToDTO(user);
            return ResponseEntity.ok(Result.success(userDTO));
        } catch (Exception e) {
            log.error("获取用户信息失败", e);
            return ResponseEntity.badRequest().body(Result.error(e.getMessage()));
        }
    }

    /**
     * 更新用户信息
     */
    @PutMapping("/profile")
    public ResponseEntity<Result<UserDTO>> updateProfile(
            @RequestHeader("Authorization") String token,
            @Valid @RequestBody UserDTO userDTO) {
        log.info("更新用户信息请求");
        try {
            User currentUser = userService.getCurrentUser(token);
            UserDTO responseDTO = userService.updateUser(currentUser.getId(), userDTO);
            return ResponseEntity.ok(Result.success(responseDTO, "更新成功"));
        } catch (Exception e) {
            log.error("更新用户信息失败", e);
            return ResponseEntity.badRequest().body(Result.error(e.getMessage()));
        }
    }

    /**
     * 修改密码
     */
    @PutMapping("/password")
    public ResponseEntity<Result<String>> changePassword(
            @RequestHeader("Authorization") String token,
            @Valid @RequestBody ChangePasswordRequest request) {
        log.info("修改密码请求");
        try {
            User currentUser = userService.getCurrentUser(token);
            userService.changePassword(currentUser.getId(), request.getOldPassword(), request.getNewPassword());
            return ResponseEntity.ok(Result.success(null, "密码修改成功"));
        } catch (Exception e) {
            log.error("修改密码失败", e);
            return ResponseEntity.badRequest().body(Result.error(e.getMessage()));
        }
    }

    /**
     * 根据ID获取用户信息
     */
    @GetMapping("/{id}")
    public ResponseEntity<Result<UserDTO>> getUserById(@PathVariable Long id) {
        log.debug("根据ID获取用户信息，ID: {}", id);
        try {
            User user = userService.findById(id);
            UserDTO userDTO = convertToDTO(user);
            return ResponseEntity.ok(Result.success(userDTO));
        } catch (Exception e) {
            log.error("获取用户信息失败", e);
            return ResponseEntity.badRequest().body(Result.error(e.getMessage()));
        }
    }

    /**
     * 分页查询用户列表
     */
    @GetMapping
    public ResponseEntity<Result<Page<UserDTO>>> getUsers(
            @RequestParam(defaultValue = "0") @Min(0) int page,
            @RequestParam(defaultValue = "20") @Min(1) @Max(100) int size,
            @RequestParam(defaultValue = "createdAt") String sortBy,
            @RequestParam(defaultValue = "desc") String sortDir) {
        log.debug("分页查询用户列表，页码: {}, 大小: {}", page, size);
        try {
            Sort.Direction direction = "desc".equalsIgnoreCase(sortDir) 
                ? Sort.Direction.DESC : Sort.Direction.ASC;
            Pageable pageable = PageRequest.of(page, size, Sort.by(direction, sortBy));
            
            Page<User> userPage = userService.findAll(pageable);
            Page<UserDTO> userDTOPage = userPage.map(this::convertToDTO);
            
            return ResponseEntity.ok(Result.success(userDTOPage));
        } catch (Exception e) {
            log.error("查询用户列表失败", e);
            return ResponseEntity.badRequest().body(Result.error(e.getMessage()));
        }
    }

    /**
     * 搜索用户
     */
    @GetMapping("/search")
    public ResponseEntity<Result<Page<UserDTO>>> searchUsers(
            @RequestParam String keyword,
            @RequestParam(defaultValue = "0") @Min(0) int page,
            @RequestParam(defaultValue = "20") @Min(1) @Max(100) int size) {
        log.debug("搜索用户，关键字: {}", keyword);
        try {
            Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createdAt"));
            Page<User> userPage = userService.searchUsers(keyword, pageable);
            Page<UserDTO> userDTOPage = userPage.map(this::convertToDTO);
            
            return ResponseEntity.ok(Result.success(userDTOPage));
        } catch (Exception e) {
            log.error("搜索用户失败", e);
            return ResponseEntity.badRequest().body(Result.error(e.getMessage()));
        }
    }

    /**
     * 检查用户名是否可用
     */
    @GetMapping("/check-username")
    public ResponseEntity<Result<Boolean>> checkUsernameAvailability(@RequestParam String username) {
        log.debug("检查用户名可用性: {}", username);
        try {
            boolean available = userService.isUsernameAvailable(username);
            return ResponseEntity.ok(Result.success(available, 
                available ? "用户名可用" : "用户名已存在"));
        } catch (Exception e) {
            log.error("检查用户名可用性失败", e);
            return ResponseEntity.badRequest().body(Result.error(e.getMessage()));
        }
    }

    /**
     * 检查邮箱是否可用
     */
    @GetMapping("/check-email")
    public ResponseEntity<Result<Boolean>> checkEmailAvailability(@RequestParam String email) {
        log.debug("检查邮箱可用性: {}", email);
        try {
            boolean available = userService.isEmailAvailable(email);
            return ResponseEntity.ok(Result.success(available, 
                available ? "邮箱可用" : "邮箱已存在"));
        } catch (Exception e) {
            log.error("检查邮箱可用性失败", e);
            return ResponseEntity.badRequest().body(Result.error(e.getMessage()));
        }
    }

    /**
     * 激活用户账户
     */
    @PutMapping("/{id}/activate")
    public ResponseEntity<Result<UserDTO>> activateUser(@PathVariable Long id) {
        log.info("激活用户账户，ID: {}", id);
        try {
            User user = userService.activateUser(id);
            UserDTO userDTO = convertToDTO(user);
            return ResponseEntity.ok(Result.success(userDTO, "用户激活成功"));
        } catch (Exception e) {
            log.error("激活用户账户失败", e);
            return ResponseEntity.badRequest().body(Result.error(e.getMessage()));
        }
    }

    /**
     * 禁用用户账户
     */
    @PutMapping("/{id}/deactivate")
    public ResponseEntity<Result<UserDTO>> deactivateUser(@PathVariable Long id) {
        log.info("禁用用户账户，ID: {}", id);
        try {
            User user = userService.deactivateUser(id);
            UserDTO userDTO = convertToDTO(user);
            return ResponseEntity.ok(Result.success(userDTO, "用户禁用成功"));
        } catch (Exception e) {
            log.error("禁用用户账户失败", e);
            return ResponseEntity.badRequest().body(Result.error(e.getMessage()));
        }
    }

    /**
     * 删除用户
     */
    @DeleteMapping("/{id}")
    public ResponseEntity<Result<String>> deleteUser(@PathVariable Long id) {
        log.info("删除用户，ID: {}", id);
        try {
            boolean deleted = userService.deleteUser(id);
            if (deleted) {
                return ResponseEntity.ok(Result.success(null, "用户删除成功"));
            } else {
                return ResponseEntity.badRequest().body(Result.error("用户不存在"));
            }
        } catch (Exception e) {
            log.error("删除用户失败", e);
            return ResponseEntity.badRequest().body(Result.error(e.getMessage()));
        }
    }

    /**
     * 获取用户统计信息
     * TODO: 需要实现UserStats类和getUserStats方法
     */
    /*
    @GetMapping("/stats")
    public ResponseEntity<Result<UserService.UserStats>> getUserStats() {
        log.debug("获取用户统计信息");
        try {
            UserService.UserStats stats = userService.getUserStats();
            return ResponseEntity.ok(Result.success(stats));
        } catch (Exception e) {
            log.error("获取用户统计信息失败", e);
            return ResponseEntity.badRequest().body(Result.error(e.getMessage()));
        }
    }
    */

    /**
     * 转换User实体为UserDTO
     */
    private UserDTO convertToDTO(User user) {
        UserDTO dto = new UserDTO();
        dto.setId(user.getId());
        dto.setUsername(user.getUsername());
        dto.setEmail(user.getEmail());
        dto.setNickname(user.getNickname());
        dto.setAvatarUrl(user.getAvatarUrl());
        dto.setStatus(user.getStatus());
        dto.setRole(user.getRole().name());
        dto.setLastLoginTime(user.getUpdatedAt()); // 使用updatedAt作为最后登录时间的替代
        dto.setCreatedAt(user.getCreatedAt());
        dto.setUpdatedAt(user.getUpdatedAt());
        return dto;
    }

    /**
     * 修改密码请求DTO
     */
    public static class ChangePasswordRequest {
        @jakarta.validation.constraints.NotBlank(message = "旧密码不能为空")
        private String oldPassword;
        
        @jakarta.validation.constraints.NotBlank(message = "新密码不能为空")
        @jakarta.validation.constraints.Size(min = 6, max = 20, message = "新密码长度必须在6-20之间")
        private String newPassword;

        public String getOldPassword() { return oldPassword; }
        public void setOldPassword(String oldPassword) { this.oldPassword = oldPassword; }
        public String getNewPassword() { return newPassword; }
        public void setNewPassword(String newPassword) { this.newPassword = newPassword; }
    }

    /**
     * 获取客户端IP地址
     */
    private String getClientIp(HttpServletRequest request) {
        String xForwardedFor = request.getHeader("X-Forwarded-For");
        if (xForwardedFor != null && !xForwardedFor.isEmpty() && !"unknown".equalsIgnoreCase(xForwardedFor)) {
            return xForwardedFor.split(",")[0];
        }
        String xRealIp = request.getHeader("X-Real-IP");
        if (xRealIp != null && !xRealIp.isEmpty() && !"unknown".equalsIgnoreCase(xRealIp)) {
            return xRealIp;
        }
        return request.getRemoteAddr();
    }
}
